<template>
    <n-space class="wh-full" :vertical="false" :wrap-item="false">
        <!-- 菜单树 -->
        <n-card class="left-card">
            <n-space>
                <n-button type="primary" size="medium" @click="handleAddMenu">
                    <template #icon>
                        <icon-ri:add-circle-fill></icon-ri:add-circle-fill>
                    </template>
                    添加菜单
                </n-button>
                <n-button type="primary" size="medium" @click="() => openAll = !openAll">
                    全部{{ openAll ? "收起" : "展开" }}
                </n-button>
            </n-space>
            <n-space vertical :size="12" class="mt-xs">
                <n-input v-model:value="pattern" size="small" placeholder="搜索" clearable>
                    <template #suffix>
                        <icon-ic:round-search></icon-ic:round-search>
                    </template>
                </n-input>
                <n-tree block-line :data="obj2any(menuTree)" :pattern="pattern" key-field="id" label-field="name"
                    children-field="children" expand-on-click selectable :render-prefix="buildMenuPrefix"
                    :render-suffix="buildMenuSuffix" :node-props="buildNodeProps" :default-expand-all="openAll"
                    :on-update:selected-keys="handleMenuTreeSelected" />
            </n-space>

        </n-card>
        <!-- 编辑框 -->
        <n-card class="right-card" segmented>
            <template #header>
                编辑框
            </template>
            <n-form :model="form"  ref="formRef" :rules="rules" label-width="80"  label-placement="left"
                class="fi-w mx-auto" :inline="false">
                <n-form-item label="上级菜单" path="parentId">
                    <n-tree-select :options="obj2any(menuTree)" label-field="name" key-field="id" children-field="children"
                        v-model:value="form.parentId" clearable />
                </n-form-item>
                <n-form-item label="菜单类型" path="type">
                    <n-radio-group v-model:value="form.type">
                        <n-space>
                            <n-radio :value="SysMenuType.Menu">目录</n-radio>
                            <n-radio :value="SysMenuType.Page">页面</n-radio>
                            <n-radio :value="SysMenuType.Button">按钮</n-radio>
                        </n-space>
                    </n-radio-group>
                </n-form-item>
                <n-form-item label="菜单图标" path="icon">
                    <icon-select v-model:value="form.icon" :icons="icons"></icon-select>
                </n-form-item>
                <n-form-item label="菜单名" path="name">
                    <n-input v-model:value="form.name" placeholder="请输入菜单名" />
                </n-form-item>
                <n-form-item label="菜单路径" path="menuKey">
                    <n-auto-complete :options="menuKeyOptions" :get-show="getMenuKeyOptionShow" v-model:value="form.menuKey" placeholder="请输入菜单路径（以_分割）" />
                </n-form-item>
                <n-form-item label="路由" path="path">
                    <n-input v-model:value="form.path" placeholder="请输入路由" />
                </n-form-item>
								<n-form-item label="外链地址" path="href">
                    <n-input v-model:value="form.href" placeholder="请输入权限字符" />
                </n-form-item>
                <n-form-item label="权限字符" path="permission">
                    <n-input v-model:value="form.permission" placeholder="请输入权限字符" />
                </n-form-item>
								<n-form-item label="权重" path="weight">
                    <n-input-number v-model:value="form.weight" placeholder="请输入权重" />
                </n-form-item>
                <n-form-item label="状态" path="status">
                    <n-radio-group v-model:value="form.status">
                        <n-space>
                            <n-radio :value="BusinessStatus.Yes">启用</n-radio>
                            <n-radio :value="BusinessStatus.No">禁用</n-radio>
                        </n-space>
                    </n-radio-group>
                </n-form-item>
                <n-form-item label="其他">
                    <n-space item-style="display: flex;">
                        <n-checkbox v-model:checked="form.keepAlive" label="缓存"
                        :checked-value="BusinessStatus.Yes" :unchecked-value="BusinessStatus.No" />
                        <n-checkbox v-model:checked="form.iframe" label="外链"
                        :checked-value="BusinessStatus.Yes" :unchecked-value="BusinessStatus.No" />
                        <n-checkbox v-model:checked="form.hide" label="隐藏"
                        :checked-value="BusinessStatus.Yes" :unchecked-value="BusinessStatus.No" />
												<n-checkbox v-model:checked="form.watermark" label="水印"
                        :checked-value="BusinessStatus.Yes" :unchecked-value="BusinessStatus.No" />
                    </n-space>
               </n-form-item>

            </n-form>
            <template #footer >
                <n-space justify="center">
                    <n-button type="success" secondary @click="onSubmit">确定</n-button>
                    <n-button type="warning" secondary @click="onReset">重置</n-button>
                    <n-button type="error" secondary :disabled="!form.id" @click="(e)=>{handleRemoveNode(e,form)}">删除</n-button>
                </n-space>
            </template>
        </n-card>

        <batchAddBtn v-model:visible="showAddBtn" :pId="editPageId" @submitted="getMenuTree"/>
    </n-space>
</template>

<script  setup lang='tsx' >
import { views } from '@/router/elegant/imports'
import { fetchMenuTree,fetchAddMenu,fetchUpdateMenu,fetchDeleteMenu } from '@/service/api/sys/menu'
import { h, ref, onMounted, unref, VNodeChild} from 'vue';
import { Icon } from '@iconify/vue';
import { FormInst, NButton, NSpace, TreeOption } from 'naive-ui'
import TooltipBtn from "~/src/components/custom/tooltip-btn.vue"
import { BusinessStatus } from '~/src/enum';
import { SysMenuType, icons } from './index'
import { obj2any } from '~/src/utils/common';
import { TreeRenderProps } from 'naive-ui/es/tree/src/interface';
import { computed } from 'vue';
import { FlatResponseData } from '~/packages/axios/src/type';
import batchAddBtn from './batchAddBtn.vue';
import iconSelect from '~/src/components/custom/icon-select.vue';

interface DataSource extends SysAuth.SysMenu { }

const staticMenu = computed(()=>{
	const temp = [];
	for(const view in views){
		temp.push(view)
	}
	return temp;
})
const menuKeyOptions = ref<string[]>([])

const openAll = ref<boolean>(false);
const pattern = ref<string>();
const menuTree = ref<DataSource[]>()

const curNode = ref<DataSource|null>(null)

const form = ref<DataSource>(initFormData())
const rules = {
	name:{ required: true, message: "请输入菜单名", trigger: 'input' },
	menuKey:{ required: true, message: "请输入菜单路径", trigger: 'input' },
	path:{ required: true, message: "请输入路由", trigger: 'input' },
}
const formRef = ref<FormInst|null>(null)

const showAddBtn = ref<boolean>(false)
const editPageId = ref<Common.IdType|null>(null)
async function getMenuTree() {
    const { data } = await fetchMenuTree()
    menuTree.value = data!
}

function buildMenuPrefix(info: { option: TreeOption, checked: boolean, selected: boolean }) {
    return <Icon icon={info.option.icon as string}></Icon>
}
function buildMenuSuffix(info: TreeRenderProps ): VNodeChild | undefined {
    const row = info.option as unknown as DataSource
    return [
        h(NSpace, { justify: "center", class: "suffix", size: 5 }, [
            row.type === 'P' ?
            h(TooltipBtn, { str: "新增按钮", size: "small", type: "primary", icon: "fluent:layer-diagonal-add-20-filled", localIcon:false,ghost: true,secondary:false,bordered:false, onClick: (e) => { handleAddBtn(e,row.id!) } })
            :'',
            h(TooltipBtn, { str: "新增", size: "small", type: "primary", icon: "ri-add-circle-fill", localIcon:true,ghost: true,secondary:false,bordered:false, onClick: (e) => { handleAddChild(e,row.id!) } }),
            h(TooltipBtn, { str: "删除", size: "small", type: "error", icon: "ri-delete-bin-2-line", localIcon:true,ghost: true,secondary:false,bordered:false, onClick: (e) => { handleRemoveNode(e,row)} }),
        ])
    ]
}
function handleAddBtn(e:MouseEvent,id:string|number){
    e.stopPropagation()
    editPageId.value = id;
    showAddBtn.value = true

}
function buildNodeProps() {
    return {
        class: "sys-menu-tree-node"
    }
}
function handleAddChild(e:MouseEvent,id:string|number){
    e.stopPropagation()
    const addForm = initFormData()
    addForm.parentId = id
    form.value = addForm;
}
function handleRemoveNode(e:MouseEvent,node:DataSource){
    e.stopPropagation()
		if(!node.id){
			return;
		}
    if(node.children && node.children.length == 0){
        window.$message?.error("不可删除有子节点的菜单！")
        return
    }
    window.$dialog?.create({
        content:`是否确认删除[${node.name}]菜单`,
        negativeText:'取消',
        positiveText:'确定',
        onPositiveClick:()=>{
           fetchDeleteMenu(node.id!).then(handleFetchResult)
        }
    })

}
function handleMenuTreeSelected(keys: Array<string | number>, option: Array< null | DataSource>):undefined{
	curNode.value = option[0]
	form.value = initFormData(curNode.value||undefined)
	return undefined;
}
function handleAddMenu(){
	curNode.value = null ;
	form.value = initFormData()
}
function initFormData(data?: DataSource): DataSource {
    const temp = unref(data!)
    return {
        id: temp?.id||undefined,
        name: temp?.name || '',
        parentId: data?.parentId || '',
        weight: data?.weight || 0,
        path: data?.path || '/',
        menuKey: data?.menuKey || '',
        type: data?.type || SysMenuType.Menu,
        permission: data?.permission || '',
        icon: data?.icon || '',
        iframe: data?.iframe || BusinessStatus.No,
        hide: data?.hide || BusinessStatus.No,
        status: data?.status || BusinessStatus.Yes,
        keepAlive: data?.keepAlive || BusinessStatus.Yes,
				href: data?.href || '',
				watermark:data?.watermark || BusinessStatus.No,
        children: [],
    }
}

function onSubmit() {
    formRef.value?.validate(e=>{
        if(!e){
            if(form.value.id){
                fetchUpdateMenu(form.value).then(handleFetchResult)
            }else{
                fetchAddMenu(form.value).then(handleFetchResult)
            }
        }
    })
}
function onReset(){
    formRef.value?.restoreValidation();
    form.value = initFormData(curNode.value||undefined)
}
function handleFetchResult(res: FlatResponseData<any, App.Service.Response<unknown>>) {
    if (!res.error) {
      getMenuTree()
      window.$message?.success("操作成功")
    }
}
function getMenuKeyOptionShow(val:string){
	if(!val){
		return false;
	}
	menuKeyOptions.value = staticMenu.value.filter(it=>it.startsWith(val))
	return menuKeyOptions.value && menuKeyOptions.value.length > 0
}

onMounted(() => {
    getMenuTree()
})
</script>

<style lang='scss' scoped>
.left-card {
    height: 100%;
    min-width: 350px;
    max-width: 450px;
    flex: 4;
}

.right-card {
    height: 100%;
    min-width: 500px;
    flex: 6;
}

:deep(.sys-menu-tree-node) {
    .suffix {
        visibility: hidden;
    }

    &:hover .suffix {
        visibility: visible;
    }
}
</style>
